<?php

/**
 * @Author: king
 * @Date:   2019-05-01 13:49:20
 * @Last Modified by:   king
 * @Last Modified time: 2019-05-01 14:22:27
 */


namespace App\Models\Api;
use App\Exceptions\ApiException;
use App\Models\Api\Base;
use Cache;


class AstroCounselor extends Base
{
    const COUNSELOR_ALL_IDS = 'counselor:all:ids';//所有咨询师id
    const COUNSELOR_HOT_IDS = 'counselor:hot:ids';//热门咨询师id
    const COUNSELOR_INFO = ':counselor:info:';//用户咨询师信息详情
    const CACHE_TIME = 86400 * 7;//缓存时间
    protected $table = 'wechat.zhunle_counselor';

    /**
     * 保存或编辑咨询师信息
     * @param array $data
     * @param array $id
     * @return bool|false|int
     */
    public function saveCounselor($data = [], $id = [])
    {
        if (empty($id)) {
            //新增
            try {
                $res = $this->save($data);
            } catch (\Exception $e) {
                $this->error = '保存咨询师信息失败';
                return false;
            }
        } else {
            //编辑
            try {
                $res = $this->save($data, $id);
            } catch (\Exception $e) {
                $this->error = '保存咨询师信息失败';
                return false;
            }
        }

        return $res;
    }


    /**
     * 获取咨询师列表id
     * @param array $map //筛选条件(type,price,level,grade,search)
     * @return array|bool|false|mixed|\PDOStatement|string|\think\Collection
     */
    public function getCounselorLists($map = [])
    {
        $where = [];
        $is_or = 0;
        $start_price = 0;
        $end_price = 999999;

        $start_level = 0;
        $end_level = 999999;

        //根据价格,等级进行筛选
        if ($map['type'] == 0 && $map['search'] == '') {
            $is_or = 1;
            switch (true) {
                case $map['price'] == 1:
                    $end_price = 100;
                    break;
                case $map['price'] == 2:
                    $start_price = 101;
                    $end_price = 300;
                    break;
                case $map['price'] == 3:
                    $start_price = 301;
                    $end_price = 500;
                    break;
                case $map['price'] == 4:
                    $start_price = 501;
                    break;
                case $map['level'] == 1:
                    $end_level = 1;
                    break;
                case $map['level'] == 2:
                    $start_level = 1;
                    $end_level = 2;
                    break;
                case $map['level'] == 3:
                    $start_level = 2;
                    $end_level = 3;
                    break;
                case $map['level'] == 4:
                    $start_level = 3;
                    break;
            }
        } else {
            //根据占星进行筛选
            if ($map['type'] == 1) {
                $type_name = 'stargazer_';
            } //根据占卜进行筛选
            else {
                $type_name = 'divination_';
            }

            switch (true) {
                case $map['price'] == 1:
                    $where[$type_name . 'price'] = ['between', [$start_price, 100]];
                    break;
                case $map['price'] == 2:
                    $where[$type_name . 'price'] = ['between', [101, 300]];
                    break;
                case $map['price'] == 3:
                    $where[$type_name . 'price'] = ['between', [301, 500]];
                    break;
                case $map['price'] == 4:
                    $where[$type_name . 'price'] = ['between', [501, $end_price]];
                    break;
                case $map['level'] == 1:
                    $where[$type_name . 'level'] = 1;
                    break;
                case $map['level'] == 2:
                    $where[$type_name . 'level'] = 2;
                    break;
                case $map['level'] == 3:
                    $where[$type_name . 'level'] = 3;
                    break;
                case $map['level'] == 4:
                    $where[$type_name . 'level'] = ['>', 3];
                    break;
            }

        }
        //根据评分进行筛选
        if ($map['grade']) {
            switch (true) {
                case $map['grade'] == 1:
                    $where['star_level'] = 5;
                    break;
                case $map['grade'] == 2:
                    $where['star_level'] = 4;
                    break;
                case $map['grade'] == 3:
                    $where['star_level'] = 3;
                    break;
                case $map['grade'] == 4:
                    $where['star_level'] = ['<', 3];
                    break;
            }
        }

        if ($map['search']) {
            $where = ['nickname' => ['like', '%' . $map['search'] . '%']];
        }

        if ($is_or === 0) {
            try {
                $uids = $this->where($where)->column('id');

                // 将咨询师id组成字符串
                $uids = implode(',', $uids);

                // 缓存咨询师id,根据咨询师id
                if ($uids && $this->cache_on >= 1) {
                    Cache::set(self::COUNSELOR_ALL_IDS, $uids, self::CACHE_TIME);
                }

            } catch (\Exception $e) {
                $this->error = '获取咨询师列表失败';
                return false;
            }
        } else {
            $whereOr = "(divination_level between $start_level AND $end_level OR stargazer_level between $start_level AND $end_level) AND (divination_price between $start_price AND $end_price OR stargazer_price between $start_price AND $end_price)";
            try {
                $uids = $this
                    ->where($where)
                    ->where($whereOr)
                    ->column('id');

                // 将咨询师id组成字符串
                $uids = implode(',', $uids);

                // 缓存咨询师id,根据咨询师id
                if ($uids && $this->cache_on >= 1) {
                    Cache::set(self::COUNSELOR_ALL_IDS, $uids, self::CACHE_TIME);
                }

            } catch (\Exception $e) {
                $this->error = '获取咨询师列表失败';
                return false;
            }
        }

        // 将咨询师id转为数组
        $all_course_ids = explode(',', $uids);

        $per_page = 10;// 当前文章评论每页显示数量

        // 统计有多少咨询师
        $total = count($all_course_ids);
        //获取数据分页信息
        $data_list = getPaginatorData($total, $map['page'], $per_page);

        //获取分页后的咨询师id数组
        $all_course_id = array_slice($all_course_ids, $data_list['start'], $per_page);

        unset($data_list['start']);
        unset($data_list['end']);

        $data = [];
        // 根据当前页课程id获取所需的课程信息
        if (!empty($all_course_id)) {
            $ac_ids = [];
            $temp = [];

            // 从缓存课程内容,根据课程id
            foreach ($all_course_id as $ac_id) {
                if ($this->cache_on >= 1) {
                    // 根据课程id 获取课程内容
                    $temp[$ac_id] = Cache::get($ac_id . self::COUNSELOR_INFO . $ac_id);
                } else {
                    // 缓存未开启时，默认从数据库获取
                    $temp[$ac_id] = false;
                }
                // 课程内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false && $ac_id) {
                    $ac_ids[] = $ac_id;
                }
            }

            if (!empty($ac_ids)) {
                $data = $this->getManyCounselorInfo($ac_ids);
            }

            foreach ($temp as $item) {
                if ($item) {
                    $data[] = $item;
                }
            }
        }
        $data_list['data'] = $data;
        return $data_list;
    }


    /**
     * 获取热门所有咨询师的id
     * @return array|bool|false|mixed|\PDOStatement|string|\think\Collection
     */
    public function getHotCounselor()
    {
        $page = 1;//分页起始页

        $hot_cids = false;

        if ($this->cache_on >= 1)
        {
            $hot_cids = Cache::get(self::COUNSELOR_HOT_IDS);
        }

        // 获取所有咨询师id
        if ($hot_cids === false)
        {

            $where = ['counselor_status' => 1, 'is_hot' => 1];
            try
            {
                $hot_cids = $this
                    ->where($where)
                    ->order('is_hot DESC')
                    ->column('id');

                // 将咨询师id组成字符串
                if (!empty($hot_cids))
                {
                    $hot_cids = implode(',', $hot_cids);
                }

                // 缓存咨询师id,根据咨询师id
                if ($hot_cids && $this->cache_on >= 1)
                {
                    Cache::set(self::COUNSELOR_HOT_IDS, $hot_cids, self::CACHE_TIME);
                }

            }
            catch (\Exception $e)
            {
                $this->error = '获取上架的咨询师基本信息失败';

                return false;
            }

        }
        // 将咨询师id转为数组
        $all_course_ids = explode(',', $hot_cids);

        $per_page = 10;// 当前热门咨询师每页显示数量

        // 统计有多少咨询师
        $total = count($all_course_ids);
        //获取数据分页信息
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的咨询师id数组
        $all_course_id = array_slice($all_course_ids, $data_list['start'], $per_page);

        unset($data_list['start']);
        unset($data_list['end']);

        $data = [];
        // 根据当前页咨询师id获取所需的咨询师信息
        if (!empty($all_course_id))
        {
            $ac_ids = [];
            $temp = [];

            // 从缓存咨询师内容,根据咨询师id
            foreach ($all_course_id as $ac_id)
            {
                if ($this->cache_on >= 1)
                {
                    // 根据咨询师id 获取咨询师内容
                    $temp[$ac_id] = Cache::get($ac_id . self::COUNSELOR_INFO);
                } else
                {
                    // 缓存未开启时，默认从数据库获取
                    $temp[$ac_id] = false;
                }
                // 咨询师内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false && $ac_id)
                {
                    $ac_ids [] = $ac_id;
                }
            }

            if (!empty($ac_ids)) {
                $data = $this->getManyCounselorInfo($ac_ids);
            }

            foreach ($temp as $item) {
                if ($item) {
                    $data[] = $item;
                }
            }
        }
        return $data;
    }


    /**
     * 获取某个咨询师信息
     * @param array $map
     * @return array|bool|false|mixed|\PDOStatement|string|\think\Model
     */
    public function getCounselorInfo($map = [])
    {
        if (isset($map['cid'])) {
            $where = ['c.id' => $map['cid']];
            $id = $map['cid'];
        } else {
            $where = ['c.uid' => $map['uid']];
            $id = $map['uid'];
        }
        $field = 'c.id,c.is_hot,c.uid,c.divination_level,c.stargazer_level,c.divination_integral,c.stargazer_integral,c.state,c.star_level,c.divination_price,c.stargazer_price,c.counselor_num,c.accept,c.grab_num,c.read_num,c.answer_num,c.nickname,c.intro,u.avatar,u.sex';
        try {

            $data = $this
                ->alias('c')
                ->field($field)
                ->join('wechat.app_user u', 'c.uid=u.id', 'INNER')
                ->where($where)
                ->find();
            $data = json_decode(json_encode($data, true), true);
            // 将咨询师内容缓存
            if ($this->cache_on >= 1) {
                Cache::set($id . self::COUNSELOR_INFO, $data, self::CACHE_TIME);
            }
        } catch (\Exception $e) {
            $this->error = '获取咨询师信息失败';
            return false;
        }
        return $data;
    }

    /**
     * 获取多个咨询师信息
     * @param array $cid
     * @return bool|false|mixed|\PDOStatement|string|\think\Collection
     */
    public function getManyCounselorInfo($cid = [])
    {
        // 从数据库获取咨询师内容
        $where = ['c.id' => ['in', $cid]];
        $field = 'c.id,c.is_hot,c.uid,c.divination_level,c.stargazer_level,c.divination_integral,c.stargazer_integral,c.state,c.star_level,c.divination_price,c.stargazer_price,c.counselor_num,c.accept,c.grab_num,c.read_num,c.answer_num,c.nickname,c.intro,u.avatar,u.sex';
        try {
            $data = $this
                ->alias('c')
                ->field($field)
                ->join('wechat.app_user u', 'c.uid=u.id', 'INNER')
                ->where($where)
                ->select();

            $data = json_decode(json_encode($data, true), true);

        } catch (\Exception $e) {
            $this->error = '获取咨询师基本信息失败';
            return false;
        }

        if (!empty($data)) {
            foreach ($data as $c) {
                // 将咨询师内容缓存
                if ($this->cache_on >= 1) {
                    Cache::set($c['id'] . self::COUNSELOR_INFO, $c, self::CACHE_TIME);
                }
            }
        }
        return $data;
    }

    /**
     * 获取咨询师价格
     * @param $cids
     * @param $problemType 占星/占卜
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getCounselorsPrice($cids, $problemType)
    {
        $problemTypeName = $problemType == 1 ? '占星' : '占卜';

        if ($problemType == 1)
        {
            // 占星
            $field = 'id,stargazer_level,stargazer_price,state,counselor_status,nickname';
            $counselorLevel = 'stargazer_level';
            $counselorPrice = 'stargazer_price';
        } else
        {
            // 占卜
            $field = 'id,divination_level,divination_price,state,counselor_status,nickname';
            $counselorLevel = 'divination_level';
            $counselorPrice = 'divination_price';
        }
        // 查下咨询师数据
        $dataModels = $this->whereIn('id', $cids)
            ->field($field)
            ->select();
        // 咨询师参数校验
        if (count(explode(',', $cids)) != ($people = count($dataModels)))
        {
            throw new Exception($problemTypeName . '师参数异常');
        }

        $priceData = [
            'totalPrice' => 0,
            'people' => $people,
            'counselorPrices' => []
        ];
        foreach ($dataModels as $dataModelItem)
        {
            // 接单状态验证
            if ($dataModelItem->state === 0)
            {
                throw new Exception($problemTypeName . '师 ' . $dataModelItem->nickname . ' 休息了！...');
            }
            // 咨询师判断
            if ($dataModelItem->counselor_status != 1 || $dataModelItem->{$counselorLevel} == 0)
            {
                throw new Exception($dataModelItem->nickname . ' ' . $problemTypeName . '师状态异常...');
            }
            // 统计总价
            $priceData['totalPrice'] += $dataModelItem->{$counselorPrice};
            // 组合扩展对象
            $priceData['counselorPrices'][] = [
                'id' => $dataModelItem->id,
                'level' => $dataModelItem->{$counselorLevel},
                'price' => $dataModelItem->{$counselorPrice},
                'nickname' => $dataModelItem->nickname
            ];
        }
        // 返回价格信息
        return $priceData;
    }

    /**
     * 判断用户当前是否是咨询师身份及状态
     * @param $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUserCounselorLevelInfo($uid)
    {
        $data = self::where('uid', $uid)
            ->field('id,divination_level,stargazer_level,counselor_status')->find();

        if (!$data) {
            return ['isCounselor' => false];
        }

        return [
            'isCounselor' => true,
            'id' => $data['id'],
            'divinationLevel' => $data['divination_level'],
            'stargazerLevel' => $data['stargazer_level'],
            'counselorStatus' => $data['counselor_status'],
        ];
    }

    /**
     * 用户是否是咨询师，且身份是否有效   是并且有效为true 否则为felse  和咨询师基本信息
     * @param $uid 用户ID
     * @param int $counselorType 1占星师 2占卜师 default 0 两者任何一种或两种都是
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUserCounselorStatus($uid, $counselorType = 0)
    {
        //TODO 咨询师身份 待优化 【增加字段 记录用户的占星师/占卜师/两者皆是】 及 占星师基本信息 等级 价格等
        $userCounselorLevelInfo = self::getUserCounselorLevelInfo($uid);

        if (!$userCounselorLevelInfo['isCounselor'] || $userCounselorLevelInfo['counselorStatus'] != 1) {
            return ['isCounselor' => false];
        }

        if ($counselorType == 0 && ($userCounselorLevelInfo['divinationLevel'] > 0 || $userCounselorLevelInfo['stargazerLevel'] > 0)) {
            return ['isCounselor' => true, 'cid' => $userCounselorLevelInfo['id']];
        }

        if ($counselorType == 1 && $userCounselorLevelInfo['stargazerLevel'] > 0) {
            return ['isCounselor' => true, 'cid' => $userCounselorLevelInfo['id']];
        }

        if ($counselorType == 2 && $userCounselorLevelInfo['divinationLevel'] > 0) {
            return ['isCounselor' => true, 'cid' => $userCounselorLevelInfo['id']];
        }

        return ['isCounselor' => false];
    }

    /**
     * 通过ID批量获取咨询师 头像和花名信息
     * @param $ids
     * @return array
     */
    public static function getCounselorInfoByIds($ids)
    {
        // todo 获取缓存 数据 不存在的数据  做缓存时更新方法
        $counselorInfos = self::alias('c')->whereIn('c.id', $ids)
            ->join('wechat.app_user u', 'c.uid=u.id')
            ->column('c.nickname,u.avatar', 'c.id');

        return $counselorInfos;
    }
}
